# 作者： 李泉志
# 2025年01月07日21时13分秒
# 2947029073@qq.com

# 1、把今天讲的元组，字典，字符串，集合，函数缺省参数
# 等所有接口基本功能练习一遍，和上课代码保持一致

"""
元组：
"""


def use_tuple():
    """
    元组的使用、遍历
    """
    my_tuple = ('li', 21, '男', '上海')

    # 遍历元组
    for i in my_tuple:
        print(i, end=' ')
    print()
    # 索引元组
    for i in my_tuple:
        print(f'索引 {my_tuple.index(i)} 对应元素 {i},', end=' ')
    print()
    # 按索引访问元组元素
    for i in range(len(my_tuple)):
        print(my_tuple[i], end=' ')
    print()
    # 统计计数
    print(f'元组中li的个数为{my_tuple.count('li')}')


def use_tuple_str():
    """
    格式化字符串
    """
    info_tuple = ('li', 18, 1.80)
    info_str = "%s的年龄是%d，身高%.2f" % info_tuple
    print("%s的年龄是%d，身高%.2f" % info_tuple)
    print(info_str)


def use_tuple_error():
    """
    元组的错误使用
    """
    b = ()
    print(type(b))
    c = (1,)  # 不能是d = (1),这个是int
    print(type(c))
    b = (1, 2, 3)
    d = list(b)  # 元组转换为列表,注意元组的元素不能修改
    print(d)
    print(type(d))


"""
字典：
"""


def use_dict():
    # 定义字典
    li = {'name': 'li', 'age': 21, 'gender': '男'}
    print(f'li:{li}')  # 没有li[0]

    # 1.取值
    print(f'li\'s name:{li['name']}')  # 输出小明

    # 2.增、改
    li['age'] = 23  # key存在就修改
    li['city'] = '北京'  # key不在就新增
    print(f'new li: {li}')

    # 3.删，key不存在会报错
    print(f'pop {li.pop('city')}')  # 删除key为city的项.pop返回删除的键的值
    print(f'new li: {li}')

    # 4.统计键值对个数
    print(f'lenth of li is {len(li)}')

    # 5.合并：不一样的合并，一样的覆盖
    temp_dict = {'name': 'li', 'height': 1.75, 'age': 20}
    li.update(temp_dict)  # 不能用 +=
    print(li)

    # 6.清空字典
    li.clear()
    print(li)


# 遍历字典
def dict_iter():
    xiaoming = {'name': '小明', 'age': 18, 'gender': '男'}
    for k in xiaoming:  # k为key
        print(k, xiaoming[k])
    print('-' * 50)

    for k in xiaoming.keys():
        print(k)
    print('-' * 50)

    for v in xiaoming.values():
        print(v)
    print('-' * 50)

    for kv in xiaoming.items():
        print(kv)
    print('-' * 50)

    for k, v in xiaoming.items():
        print(k, v)


def use_list_dict():
    my_list = [{'name': 'dog', 'color': 'red'},
               {'name': 'cat', 'color': 'blue'}]

    for i in my_list:
        print(i)
        print(i['name'], i['color'])


"""
字符串：
"""


def str_find():
    """
    字符串查找
    :return:
    """
    s1 = "hello world"
    print(s1.find("ld"))  # 9


def str_replace():
    """
    字符串替换
    :return:
    """
    s1 = "hello world"
    s2 = s1.replace("ld", "LD", 1)  # 第3个参数指替换次数
    print(s2)  # hello worLD


def str_split_join():
    """
    字符串分割与连接
    :return:
    """
    s1 = "hello world 66"
    print(s1)
    print('split:', s1.split())  # 按空格分割，返回列表
    # 按l分割4次，['he', '', 'o wor', 'd20 66']
    print('split l 4:', s1.split("l", 4))

    s2 = 'abc\nbcd\nefg'
    print('splitlines:', s2.splitlines())  # 按换行符分割，返回列表
    s3 = 'abc\r\nbcd\r\nefg'  # \r是回车不是换行，光标回到最前面
    print('splitlines:', s3.splitlines())  # 效果同上句一样 ['abc', 'bcd', 'efg']
    print('splitlines True:', s3.splitlines(True))  # ['abc\r\n', 'bcd\r\n', 'efg']，保留换行符

    str_list = ['a', 'b', 'c', 'd20']
    print('join:', ''.join(str_list))  # 第一个参数是接起来含有什么
    print('join with 1:', '1'.join(str_list))  # 用1接起来  a1b1c1d


def str_slice():
    """
    字符串切片
    :return:
    """
    num_str = "123456789"
    print(num_str[0:3])  # 123:0-2
    print(num_str[3:])  # 456789:3-结束
    print(num_str[:3])  # 123:0-2
    print(num_str[:])  # 123456789:0-结束，步长为1
    print(num_str[::3])  # 147:0-结束，步长为3
    print(num_str[2::2])  # 3579:2-结束，步长为2
    print(num_str[2:-1])  # 345678:2-结束，步长为1
    print(num_str[-3:])  # 789:倒数第3位开始，到结束
    print(num_str[-2:-5:-1])  # 876:倒数第2位开始，倒数第4位，步长为-1(逆序步长1) wrong:print(num_str[-2:-5])


"""
集合：
"""


def use_set():
    set1 = {}  # 空字典，而不是集合
    print(type(set1))
    set1 = set()  # 空集合初始化
    print(type(set1))
    set1 = {1, 2, 3, 4, 5}
    print(type(set1))
    print(set1)
    # 不能set[2]


def set_operation():
    set1 = {1, 2, 3, 4}
    set2 = {4, 5, 6, 7, 8}
    print('set1:', set1)
    print('set2:', set2)

    # 添加元素
    set1.add(5)
    set1.update([6, 7])
    print('set1.add|update:', set1)
    print('-' * 50)

    # 复制集合
    set3 = set1.copy()  # copy地址不同，直接=赋值地址相同
    set4 = set1
    print(f'set1.id:{id(set1)}, set3.id:{id(set3)}, set4.id:{id(set4)}')
    print('copy set1:', set3)
    print('-' * 50)

    # 并集
    set1 = {1, 2, 3}
    set2 = {5, 6, 7}
    set1.update(set2)  # 等价set1 = set1 | set2

    # 差集
    set4 = set1.difference(set2)  # 等价set4 = set1 - set2
    print(f'{set1} 差 {set2} = ', set4)
    set1.difference_update(set2)  # 无返回值，直接在set1中删
    print('set1:', set1)

    # 交集
    set2 = {2, 3}
    set5 = set1.intersection(set2)  # 等价set5 = set1 & set2
    print(f'{set1} 交 {set2}:', set5)
    set1.intersection_update(set2)  # 无返回值，直接在set1中删
    print('set1:', set1)

    # 判断是否 无相同元素，没有返回True，有返回False
    set2 = {4, 5}
    print(f'if {set1}与{set2}无相同元素:', set1.isdisjoint(set2))  # True不相交

    # 是否为子集
    set2 = {1, 2, 3}
    print(f'if {set1} is {set2}的子集:', set1.issubset(set2))  # True，set1是set2的子集
    print('-' * 50)

    # 删除元素
    print(f'{set2} remove 2 & discard 3:', end=' ')
    set2.remove(2)  # 若不存在，报错
    set2.discard(3)  # 若不存在，不报错
    print(set2)

    # 判断元素是否存在
    print(f'if 2 in {set2}:',2 in set2)  # False


def use_generator():
    """
    集合生成式
    :return:
    """

    my_set = set(x for x in range(10))
    print(my_set)

    # 支持推导式
    my_set = {x for x in 'abracadabra' if x not in 'abc'}
    print(my_set)  # {'r', 'd20'}


"""
函数：
"""
def test_func1(num=1):
    print(num)


def test_func2(name, num=1):
    print(name, num)
# def test_func3(num=1, name)  # 错 非缺省不能放缺省后面
# print(name, num)


if __name__ == '__main__':
    # use_tuple()
    # use_str()
    # use_tuple_error()
    # use_dict()
    # dict_iter()
    # use_list_dict()
    # str_find()
    # str_replace()
    # str_split_join()
    # str_slice()
    # use_set()
    # set_operation()
    # use_generator()
    test_func2('hello')  # 对
    pass
